package com.bobo.base.utils.sign;

import android.os.Build;

import androidx.annotation.RequiresApi;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class DESDemo {

    /**
     * 固定密钥，不要泄密
     */
    public static String originKey = "GwB7q9lkBlTscFdcZBSJDTFjq";

    @RequiresApi(api = Build.VERSION_CODES.O)
    public static void main() throws Exception {
        String param = "{\n" +
                "\t\"bbsSubscribeToAdd\": {\n" +
                "\t\t\"targetId\": 0,\n" +
                "\t\t\"targetType\": 0,\n" +
                "\t\t\"targetUserId\": 0\n" +
                "\t},\n" +
                "\t\"list\": null,\n" +
                "\t\"targetId\": 0,\n" +
                "\t\"targetSubType\": 0,\n" +
                "\t\"targetType\": 0,\n" +
                "\t\"targetUserId\": 0\n" +
                "}";
//        //入参需要按 ascii 码重新编排
//        SortedMap<String, Object> params = new TreeMap<>();
//        params.putAll(JSONUtil.toBean(param, TreeMap.class));
//        String jsonStr =  JSONUtil.toJsonStr(params);
//
//        //将时间戳带入验签参数
//        String ddd = DESDemo.desEncript(Base64.getDecoder().decode(jsonStr+"202211231423"),originKey);
//        System.out.println(ddd);
        String s = DESDemo.desDecript("QSnk+v6gmALilEwRqZ7kccALpO33oxn/FpS9f5uBoYwjJGF+YghcvRZywSnRPJGdLDDA5dFjzieEZOxC+z4eGnWvzKPZOIlPJ0wAQMWCRHjhGg4x/n92rCDICV3sdxX1drQk2tSruyE0uaxpGvm7QuL3I4g8oW/QrdiPEngy6EK8t+DvXDdMB3hjBRyhMPbVrdiPEngy6EIAMrcfhJOreYYPgNsRzic3HpNA//lbDujFDKm2V1i2VGf8ZKn+9PS7ULdtYvRnVbr22JJSqRmYCQ==", originKey);
        System.out.println(Base64.getDecoder().decode(s));
    }

    /**
     * 加密算法
     *
     * @param clearText
     * @param originKey
     * @return
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static String desEncript(String clearText, String originKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance("DES"); /*提供加密的方式：DES*/
        SecretKeySpec key = getKey(originKey);  /*对密钥进行操作，产生16个48位长的子密钥*/
        cipher.init(Cipher.ENCRYPT_MODE, key); /*初始化cipher，选定模式，这里为加密模式，并同时传入密钥*/
        byte[] doFinal = cipher.doFinal(clearText.getBytes());   /*开始加密操作*/
        String encode = Base64.getEncoder().encodeToString(doFinal);    /*对加密后的数据按照Base64进行编码*/
        return encode;
    }

    /**
     * 解密算法
     *
     * @param cipherText
     * @param originKey
     * @return
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static String desDecript(String cipherText, String originKey) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
        Cipher cipher = Cipher.getInstance("DES");   /*初始化加密方式*/
        Key key = getKey(originKey);  /*获取密钥*/
        cipher.init(Cipher.DECRYPT_MODE, key);  /*初始化操作方式*/
        byte[] decode = Base64.getDecoder().decode(cipherText);  /*按照Base64解码*/
        byte[] doFinal = cipher.doFinal(decode);   /*执行解码操作*/
        return new String(doFinal);   /*转换成相应字符串并返回*/
    }

    /**
     * 获取密钥算法
     *
     * @param originKey
     * @return
     */
    public static SecretKeySpec getKey(String originKey) {
        byte[] buffer = new byte[8];
        byte[] originBytes = originKey.getBytes();
        /**
         * 防止输入的密钥长度超过64位
         */
        for (int i = 0; i < 8 && i < originBytes.length; i++) {
            buffer[i] = originBytes[i];  /*如果originBytes不足8,buffer剩余的补零*/
        }
        SecretKeySpec key = new SecretKeySpec(buffer, "DES"); /*第一个参数是密钥字节数组，第二个参数是加密方式*/
        return key;  /*返回操作之后得到的密钥*/
    }
}
